package com.sky.service.Impl;

import com.sky.dao.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private WorkSpaceServiceImpl workSpaceServiceImpl;

    /**
     * 获取营业额统计数据
     *
     * @param begin
     * @param end
     * @return
     */
    public TurnoverStatisticsVO turnoverStatistics(LocalDate begin, LocalDate end) {

        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);

        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        ArrayList<Double> turnoverList = new ArrayList<>();
        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

            HashMap map = new HashMap();
            map.put("status", Orders.COMPLETED);
            map.put("begin", beginTime);
            map.put("end", endTime);
            Double turnover = reportMapper.sumByMap(map);
            turnover = turnover == null ? 0.0 : turnover;
            turnoverList.add(turnover);
        }
        return TurnoverStatisticsVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .turnoverList(StringUtils.join(turnoverList, ","))
                .build();
    }

    @Override
    public UserVO userStatistics(LocalDate begin, LocalDate end) {
        ArrayList<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        ArrayList<Integer> newUserList = new ArrayList<>();
        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Integer newUser = reportMapper.countNewUserByDate(beginTime, endTime);
            newUserList.add(newUser);
        }

        ArrayList<Integer> userList = new ArrayList();

        for (LocalDate date : dateList) {
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Integer user = reportMapper.countUserByDate(endTime);
            userList.add(user);
        }
        return UserVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .newUserList(StringUtils.join(newUserList, ","))
                .totalUserList(StringUtils.join(userList, ","))
                .build();
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        ArrayList<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            dateList.add(begin);
        }


        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        Integer validOrderCount = reportMapper.countValidOrderByDate(endTime);

        Integer totalOrderCount = reportMapper.countOrderByDate(endTime);

        Double orderCompletionRate = (double) validOrderCount / totalOrderCount;

        List<Integer> orderCountList = new ArrayList<>();
        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
             endTime = LocalDateTime.of(date, LocalTime.MAX);
            Integer validOrderCountByDate = reportMapper.countValidOrder(beginTime, endTime);
            orderCountList.add(validOrderCountByDate);
        }
        List<Integer> validOrderCountList = new ArrayList<>();
        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            endTime = LocalDateTime.of(date, LocalTime.MAX);
            Integer validOrderCountByDate = reportMapper.countValidOrders(beginTime, endTime);
            validOrderCountList.add(validOrderCountByDate);
        }

        return OrderReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .orderCompletionRate(orderCompletionRate)
                .orderCountList(StringUtils.join(orderCountList, ","))
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount)
                .validOrderCountList(StringUtils.join(validOrderCountList, ","))
                .build();

    }

    @Override
    public TopNameVO top10(LocalDate begin, LocalDate end) {
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        List<GoodsSalesDTO> salesTop10 = reportMapper.getSalesTop10(beginTime, endTime);
        List<String> names = salesTop10.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        String nameList = StringUtils.join(names, ",");

        List<Integer> numbers = salesTop10.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
        String numberList = StringUtils.join(numbers, ",");

        return TopNameVO.builder()
                .nameList(nameList)
                .numberList(numberList)
                .build();

    }

    /**
     * 導出報表
     * @param response
     */
    public void export(HttpServletResponse response) {
        LocalDate now = LocalDate.now();
        LocalDate begin = now.minusDays(30);
        LocalDate end = now.minusDays(1);
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);

        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(1).getCell(1).setCellValue(begin+"至"+end);

            BusinessDataVO businessDataVO = workSpaceServiceImpl.getBusiness(beginTime, endTime);

            XSSFRow row3 = sheet.getRow(3);
            row3.getCell(2).setCellValue(businessDataVO.getTurnover()+"元");
            String format = String.format("%.2f", businessDataVO.getOrderCompletionRate() * 100);
            row3.getCell(4).setCellValue(format+"%");
            row3.getCell(6).setCellValue(businessDataVO.getNewUsers()+"人");

            XSSFRow row4 = sheet.getRow(4);
            row4.getCell(2).setCellValue(businessDataVO.getValidOrderCount()+"笔");
            String format1 = String.format("%.2f", businessDataVO.getUnitPrice());
            row4.getCell(4).setCellValue(format1+"元");

            for (int i = 0; i < 30; i++) {
                XSSFRow row = sheet.getRow(7 + i);
                row.getCell(1).setCellValue(begin.toString());
                beginTime = LocalDateTime.of(begin, LocalTime.MIN);
                endTime = LocalDateTime.of(begin, LocalTime.MAX);
                BusinessDataVO businessDataVO1 = workSpaceServiceImpl.getBusiness(beginTime, endTime);
                row.getCell(2).setCellValue(businessDataVO1.getTurnover()+"元");
                row.getCell(3).setCellValue(businessDataVO1.getValidOrderCount()+"笔");
                format = String.format("%.2f", businessDataVO1.getOrderCompletionRate() * 100);
                row.getCell(4).setCellValue(format+"%");
                format1 = String.format("%.2f", businessDataVO1.getUnitPrice());
                row.getCell(5).setCellValue(format1+"元");
                row.getCell(6).setCellValue(businessDataVO1.getNewUsers()+"人");

                begin = begin.plusDays(1);


            }


            ServletOutputStream out = response.getOutputStream();
            excel.write(out);
            out.flush();
            out.close();
            excel.close();
        }


        catch (IOException e) {
            e.printStackTrace();
        }






    }


}

